package com.baizhi.aop;

import com.baizhi.annotation.LogAnnotation;
import com.baizhi.entity.Log;
import com.baizhi.service.LogService;
import com.baizhi.util.IPKit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;

/*
@Configuration 声明当前类配置类 创建当前类对象
@Aspect 声明当前类为切面类
*/
@Configuration
@Aspect
public class LogAop {

    //    private Logger logger = LoggerFactory.getLogger(LogAop.class);
    @Autowired
    private LogService logService;
    /**
     * 写日志增强
     * 1.获取日志信息
     * 2.日志添加数据库
     *
     * 切点的设置
     * 1.切方法
     * 2.切注解 更灵活  @annotation(com.baizhi.annotation.LogAnnotation) 代表只有添加了LogAnnotation这个注解的
     * 方法才会被aop
     * After 后置增强
     */
    @After("@annotation(com.baizhi.annotation.LogAnnotation)")
    public void logAfter(JoinPoint joinpoint){
//        logger.debug("获取日志信息");
        Log log = new Log();
        log.setLogDate(new Date());
        //获取request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpSession session = request.getSession();
        String  name = (String) session.getAttribute("name");
        log.setAdminUsername(name);
        //使用工具获取ip地址
        String ipAddrByRequest = IPKit.getIpAddrByRequest(request);
        log.setLogIp(ipAddrByRequest);
        /**
         * 获取操作内容  例如：查询了上师数据  删除了上师数据  修改了文章数据  登录
         * 获取操作类型
         *
         * 难点：执行的方法不同 操作内容和类型也不同
         *
         * 1.自定义日志注解
         * 2.在需要记录日志的方法上添加注解
         * 3.获取注解的值 通过JoinPoint
         */
        //获取方法签名对象
        MethodSignature signature = (MethodSignature) joinpoint.getSignature();
        //通过签名对象获取被aop的方法对象
        Method method = signature.getMethod();
        //通过方法对象得到方法上的注解
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        String value = annotation.value();
        String type = annotation.type();
        log.setLogContext(value);
        log.setLogType(type);
        //logger.debug("获取所有日志信息"+Log);
        /*
        将日志添加到数据库
        */
        logService.insert(log);

    }
}

